package org.inspursc.s0517.health.evaluation.service.impl;


import com.google.common.collect.Sets;
import org.inspursc.s0517.health.evaluation.entity.Organization;
import org.inspursc.s0517.health.evaluation.service.QuestionCategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.inspursc.s0517.health.evaluation.converter.InsAnRadioConverter;
import org.inspursc.s0517.health.evaluation.converter.InsSurveyAnswerConverter;
import org.inspursc.s0517.health.evaluation.dao.InsSurveyAnswerDao;
import org.inspursc.s0517.health.evaluation.dao.OrganizationDao;
import org.inspursc.s0517.health.evaluation.dto.*;
import org.inspursc.s0517.health.evaluation.entity.InsAnRadio;
import org.inspursc.s0517.health.evaluation.entity.InsSurveyAnswer;
import org.inspursc.s0517.health.evaluation.service.InsAnRadioService;
import org.inspursc.s0517.health.evaluation.service.InsAppraiseFactoryService;
import org.inspursc.s0517.health.evaluation.service.InsSurveyAnswerService;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class InsSurveyAnswerServiceImpl implements InsSurveyAnswerService{

    @Autowired
    OrganizationDao organizationDao;

    @Autowired
    QuestionCategoryService questionCategoryService;

    @Autowired
    InsAnRadioService insAnRadioService;

    @Autowired
    InsSurveyAnswerDao insSurveyAnswerDao;

    /**
     * 1.save assessment record
     * 2.save assessment result
     * 3.return assessment report
     */
    @Override
    public InsSurveyAnswerGradeDTO saveAnswer(InsSurveyAnswerDTO insSurveyAnswerDTO, HttpServletRequest request) throws Exception {
        //判断回答数据是否被重复提交
        List<InsSurveyAnswer> surveyAnswers =
                insSurveyAnswerDao.findAllByOrganizationIdAndAppraiserIdAndDateTime(
                        insSurveyAnswerDTO.getOrganizationId(),
                        insSurveyAnswerDTO.getAppraiserId(), insSurveyAnswerDTO.getDateTime());
        if (surveyAnswers != null && surveyAnswers.size() > 0) {
            throw new Exception("该离线问卷已被提交。");
        }

        //get and change categoryIds data type to dto for assessment function
        Set<Integer> categoryIds = Sets.newHashSet();
        insSurveyAnswerDTO.getQuestions().forEach(question ->{
            categoryIds.add(question.getPrimaryCategoryId());
            categoryIds.add(question.getSecondCategoryId());
        });
        List<QuestionCategoryDTO> categoryDTOs = questionCategoryService.findBatch(categoryIds);
        Organization organization = organizationDao.getOne(insSurveyAnswerDTO.getOrganizationId());

        //call assessment function
        InsSurveyAnswer insAssessmentResult = InsAppraiseFactoryService.getAppraise(1)
                .appraise(insSurveyAnswerDTO, organization, categoryDTOs);

        //save the result of the assessment and the details of that answer
        InsSurveyAnswer newInsSurveyAnswer = saveAssessResultAndAnswerDetails(insAssessmentResult, insSurveyAnswerDTO);

        InsSurveyAnswerGradeDTO returnAssessmentResult = InsSurveyAnswerConverter.insConverterToGrade(newInsSurveyAnswer);

        return returnAssessmentResult;
    }

    /**
     * 删除评估结果
     * @param id
     * @return
     */
    @Transactional
    @Override
    public boolean deleteAnswerById(int id){
        try {
            insAnRadioService.deleteByAssessmentResultId(id);
            insSurveyAnswerDao.deleteById(id);
            return true;
        }catch (Exception e){
            throw e;
        }
    }

    @Override
    public InsSurveyAnswerGradeDTO findOneById(Integer id) {
        try {
            InsSurveyAnswer insSurveyAnswer = insSurveyAnswerDao.findById(id).get();
            return InsSurveyAnswerConverter.insConverterToGrade(insSurveyAnswer);
        }catch (Exception e){
            throw e;
        }
    }

    @Override
    public AssessmentAnswerDateilsDTO getAnswerDetailById(Integer id, HttpServletRequest request) {
        try {
            InsSurveyAnswer insSurveyAnswer = insSurveyAnswerDao.findById(id).get();
            AssessmentAnswerDateilsDTO assessmentDetailsDTO = new AssessmentAnswerDateilsDTO();
            BeanUtils.copyProperties(insSurveyAnswer, assessmentDetailsDTO);

            List<InsAnRadioDTO> radioDTOS = insAnRadioService.findAllBySuAnswerId(id);
            assessmentDetailsDTO.setQuestions(radioDTOS);

            return assessmentDetailsDTO;
        }catch (Exception e){
            throw e;
        }
    }

    @Override
    public List<InsSurveyAnswerDTO> findAllByOrganizationId(int id) {
        List<InsSurveyAnswer> answers = insSurveyAnswerDao.findAllByOrganizationId(id);
        List<InsSurveyAnswerDTO> dtos = answers.stream().map(InsSurveyAnswerConverter::converter).collect(Collectors.toList());
        return dtos;
    }

    /**
     * 保存评估结果及各项评估详情
     * @param insSurveyAnswerDTO
     * @return
     */
    @Transactional
    public InsSurveyAnswer saveAssessResultAndAnswerDetails(InsSurveyAnswer insSurveyAnswer,InsSurveyAnswerDTO insSurveyAnswerDTO){
        try {
            //assessment result
            InsSurveyAnswer newInsSurveyAnswer = insSurveyAnswerDao.save(insSurveyAnswer);

            //save survey answer record
            Integer organizationId = insSurveyAnswerDTO.getOrganizationId();
            Integer appraiserId = insSurveyAnswerDTO.getAppraiserId();
            Integer surveyId = insSurveyAnswerDTO.getSurveyId();
            List<InsAnRadio> insAnRadios = new ArrayList<>();
            for (InsAnRadioDTO insAnRadioDTO : insSurveyAnswerDTO.getQuestions()) {
                InsAnRadio radio = InsAnRadioConverter.converter(insAnRadioDTO);
                radio.setDateTime(insSurveyAnswerDTO.getDateTime());
                radio.setAppraiserId(appraiserId);
                radio.setOrganizationId(organizationId);
                radio.setAssessmentResultId(newInsSurveyAnswer.getId());
                radio.setSurveyId(surveyId);
                insAnRadios.add(radio);
            }
            insAnRadioService.saveBatchAnRadio(insAnRadios);

            return newInsSurveyAnswer;
        }catch (Exception e){
            throw e;
        }
    }
}
